package com.global.gbinventory.barang.tablemodel;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.global.gbinventory.barang.model.Merek;
import com.global.gbinventory.barang.util.TYPE;
import com.global.gbinventory.barang.util.DBMaster;
import com.global.gbinventory.barang.util.CONSTANT;
import com.global.gbinventory.barang.util.STATUS_TYPE;
import com.global.gbinventory.barang.util.Status;
import com.global.gbinventory.main.model.GBTableModel;

public class MerekTableModel extends GBTableModel{

	private static final long serialVersionUID = -8605105115637680362L;
	
	private List<Merek> merekList; //list to save all merek barang according to DB
	private List<Integer> editedMerekList; //list used to save index of all the edited tuple
	
	private DBMaster dbMaster; //utility to communicate with DB
	private TYPE type;
	
	/**
	 * constructor
	 * @param dbMaster
	 */
	public MerekTableModel(DBMaster dbMaster){
		super();
		this.dbMaster = dbMaster;
		merekList = new ArrayList<Merek>();
		editedMerekList = new ArrayList<Integer>();
		type = TYPE.MEREKs;
		initialize();
	}
	
	/**
	 * initialize the needed data
	 */
	private void initialize(){
		initTableData();
	}
	
	/**
	 * initialize the table model using the data from DB
	 * Furthermore, it also initialize the merekList
	 */
	private void initTableData(){
		List<Object[]> dbTable = dbMaster.getData(type);
		List<Object[]> tmData = new ArrayList<Object[]>();
		Object[] tmCols = null;
		
		for(Object[] obj : dbTable){
			//add data from DB to merekList
			int id = (Integer) obj[CONSTANT.MEREK_DB_ID];
			String nama = obj[CONSTANT.MEREK_DB_NAMA].toString();
			Merek merek = new Merek(id, nama);
			merekList.add(merek);
			
			//add data from DB to table model
			tmCols = new Object[type.getColumnCount()];
			tmCols[CONSTANT.MEREK_TM_NAMA] = obj[CONSTANT.MEREK_DB_NAMA];
			tmData.add(tmCols);
		}
		
		setColumnNames(type.getColumnNames());
		setData(tmData);
		
	}
	
	/**
	 * add a new empty row into Tablemodel
	 */
	public void addNewRow(){
		addRow(new Object[]{""});
	}
	
	/**
	 * return a new primary key (id) corresponding to 
	 * the autoincrement id in DB
	 * @return
	 */
	public int getNewId(){
		if(!(merekList.isEmpty())){
			Merek lastMerek = merekList.get(merekList.size() - 1);
			int lastId = lastMerek.getId();
			return lastId + 1;
		}else{
			return 1;
		}
		
	}
	
	public void addEditedTuple(int row){
		if(!(editedMerekList.contains((Object) row))){
			editedMerekList.add(row);
		}
	}
	
	public void delete(int row){
		int totalTuples = merekList.size();
		
		if(row >= totalTuples){
			removeRow(row);
		}else{
			Merek merek = merekList.get(row);
			int pk = merek.getId();
			
			try {
				dbMaster.removeTuple(type, pk);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			
			merekList.remove(row);
			removeRow(row);
		}
	}
	
	/**
	 * method use to save the new and edited tuple
	 */
	public Status save(){
		int start = merekList.size();
		
		//save all new merek into DB and add it to merekList
		if(start < getRowCount()){
			do {
				if(isEmptyTuple(start)){
					removeRow(start);
					
					if(editedMerekList.contains(start)){
						editedMerekList.remove((Object) start);
					}
					
					for(int i : editedMerekList){
						int index = editedMerekList.indexOf((Object) i);
						editedMerekList.set(index, i - 1);
					}
					
				}else{
					
					try {
						
						if(editedMerekList.contains(start)){
							editedMerekList.remove((Object) start);
						}
						
						Object[] tuple = getTuple(start);
						dbMaster.addNewTuple(type, tuple);
						
						Merek newMerek = new Merek(getNewId(), tuple[CONSTANT.MEREK_TM_NAMA].toString());
						merekList.add(newMerek);
						
						start++;
					} catch (SQLException e) {
						e.printStackTrace();
					}
					
				}
			} while (start < getRowCount());
		}
		
		//save edited tuple into DB
		for(Integer row : editedMerekList){
			Object[] tuple = getTuple(row);
			String nama = tuple[CONSTANT.MEREK_TM_NAMA].toString();
			if(nama.equals("")){
				return new Status(STATUS_TYPE.ERROR_EMPTY_TUPLE);
			}else{
				//edit corresponding merek in merekList
				Merek merek = merekList.get(row);
				int pk = merek.getId();
				merek.setNama(tuple[CONSTANT.MEREK_TM_NAMA].toString());
				
				//edit corresponding tuple in DB
				try {
					dbMaster.updateTuple(type, pk, tuple);
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		
		editedMerekList.clear();
		return new Status(STATUS_TYPE.SUCCESS);
		
	}
	
	@Override
    public boolean isCellEditable(int row, int col) {
    	return true;
    }
	
	public String getMerekNama(int index){
		return merekList.get(index).getNama();
	}
	
}